באג אבטחה קריטי בגרסה 5.3.6 ומטה של PHP התגלה לפומבי ומאפשר להחדיר קובץ לתיקיית c:\windows או / בלינוקס דרך מנגנון העלאת קבצים פשוט.
כשהדפדפן שולח לשרת קובץ, יחד איתו הוא שולח גם את שמו של הקובץ. דפדפנים מסוימים (כמו אקספלורר) שולחים לא רק את שם הקובץ המועלה, אלא גם את הנתיב המלא שלו. למשל:
C:\users\me\Desktop\upload.jpg
הצד של PHP
למטרות אבטחה (וגם כדי לתקן באגים של אקספלורר) PHP חותכת את הנתיב ומשאירה במשתנה $_FILES רק את שם הקובץ עצמו (upload.jpg). באג #54939 מצא שנתיב שמתחיל בסלאש / או באקסלאש \ ולא מכיל יותר סלאשים - נשאר כפי שהוא.
כלומר, אם הדפדפן שלכם העביר בתור נתיב של הקובץ את /upload.jpg — הנתיב יישאר כפי שהוא, עם הסלאש.
הפרצה
הפרצה מופיע ברגע שמעבירים את נתיב הקובץ ישירות לפונקציה move_uploaded_files שמטרתה היא להעביר את הקובץ המועלה לתיקיה שנגדיר.
בגלל הסלאש שנשאר - המיקום שאליו הקובץ יועתק הוא תיקיה ה-root של השרת ולא התיקיה הנוכחית (כפי שהיה קורה לולא הסלאש). במקרה של Windows זוהי C:\Windows ובמקרה של unix זוהי /.
במקרים האלה, הקובץ המועלה יגיע ישירות לתיקיה ויאפשר הוספה של קבצים לאותה תיקיה או החלפת קבצים ישנים בקבצים חדשים בעזרת העלאה.
שלב ההגדרות
כמובן שאף אחד לא ייתן לתוכנת PHP להחליף קובץ בתיקיה הראשית של מערכת ההפעלה, לפחות לא ב-UNIX, מכיוון ששם השרת בדרך כלל מורץ תחת שם משתמש אחר שאין לו הרשאות לשינוי הקבצים ב-/.
לעומת זאת, ב-Windows, רובו המכריע של השרתים רץ עם הרשאות מרביות, ובמקרה הזה הקוד אכן יחליף את הקבצים או ייצור קבצים חדשים ב-C:\windows.
תמצית
כדי שהפרצה הזאת תשפיע על המערכת חייבים להתקיים שני תנאים:
[*] השרת מופעל עם משתמש בעל הרשאות כתיבה לתיקיית מערכת ההפעלה
[*] שם הקובץ מועבר אל move_uploaded_file כפי שהוא (בלי הוספת תיקייה בתחילת הנתיב)
לא בטוח שמערכת העלאת הקבצים שלכם מושפעת מזה, אבל קחו בחשבון. :-)
תגובות לכתבה:
אהלן,
אחלה מדריך!
ואם כבר לא להתבייש, אז יש לי הערה קטנה.
שגיאות כתיב-בתור מתכנת אתרים, לדעתי כתיבה נכונה(שגיאות כתיב, נוסח וכו'...) היא בראש ובראשונה מדד לגבי איכות האתר והתוכן שמוצג בו.
נשמע ממש מעניין. לא ידעתי על זה, תודה רבה!